package ext.tianma.bom.util;

import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import com.ptc.core.htmlcomp.util.TypeHelper;
import com.ptc.core.logging.Log;
import com.ptc.core.logging.LogFactory;
import com.ptc.core.lwc.server.LWCNormalizedObject;
import com.ptc.core.meta.common.IllegalFormatException;
import com.ptc.core.meta.common.TypeIdentifier;
import com.ptc.core.meta.common.TypeInstanceIdentifier;
import com.ptc.core.meta.common.UpdateOperationIdentifier;
import com.ptc.core.meta.type.common.TypeInstance;
import com.ptc.core.meta.type.common.TypeInstanceFactory;

import wt.fc.ObjectReference;
import wt.fc.Persistable;
import wt.fc.PersistenceHelper;
import wt.fc.QueryResult;
import wt.iba.definition.BooleanDefinition;
import wt.iba.definition.FloatDefinition;
import wt.iba.definition.IntegerDefinition;
import wt.iba.definition.StringDefinition;
import wt.iba.definition.TimestampDefinition;
import wt.iba.definition.litedefinition.AttributeDefDefaultView;
import wt.iba.definition.litedefinition.BooleanDefView;
import wt.iba.definition.litedefinition.FloatDefView;
import wt.iba.definition.litedefinition.IntegerDefView;
import wt.iba.definition.litedefinition.StringDefView;
import wt.iba.definition.litedefinition.TimestampDefView;
import wt.iba.definition.service.IBADefinitionHelper;
import wt.iba.value.BooleanValue;
import wt.iba.value.FloatValue;
import wt.iba.value.IBAHolder;
import wt.iba.value.IntegerValue;
import wt.iba.value.StringValue;
import wt.iba.value.TimestampValue;
import wt.pds.StatementSpec;
import wt.query.QuerySpec;
import wt.query.SearchCondition;
import wt.session.SessionHelper;
import wt.type.ClientTypedUtility;
import wt.util.WTException;

/**
 * replace IBAUtil
 * 
 * @version 1.0 $Created on 2011-8-25 $
 * @author <a href="mailto:age@ptc.com">Ge Aiping</a>
 * 
 */
public class LWCUtil {
    private static Log log = LogFactory.getLog(LWCUtil.class);
    
    public static boolean hasAttribute(Persistable p, String attName){
        Locale loc=null;
        try {
            loc = SessionHelper.getLocale();
        } catch (WTException e) {
            e.printStackTrace();
            return false;
        }
        TypeInstance typeInstance;
        try {
            LWCNormalizedObject lwcObject = new LWCNormalizedObject(p, null, loc, null);
            TypeInstanceIdentifier typeinstanceidentifier = ClientTypedUtility.getTypeInstanceIdentifier(p);
            typeInstance = TypeInstanceFactory.newTypeInstance(typeinstanceidentifier);
            
            TypeIdentifier typeidentifier = (TypeIdentifier)typeInstance.getIdentifier().getDefinitionIdentifier();
            Set attrs=TypeHelper.getSoftAttributes(typeidentifier);
            Iterator attIt=attrs.iterator();
            String attrFullName="";
            String attrName="";
            int idx=0;
            while(attIt.hasNext()){
                attrFullName=attIt.next().toString();
                idx=attrFullName.lastIndexOf("|");
                attrName=attrFullName.substring(idx+1);
                if(attrName.equals(attName)){
                	return true;
                }
            }

        } catch (IllegalFormatException e) {
            e.printStackTrace();
        } catch (WTException e) {
            e.printStackTrace();
        }
        return false;
    }
    /**
     * 
     * @param p
     * @return
     */
    public static Map<String, Object> getAllAttribute(Persistable p,Locale loc) {
        log.info("$$$$$$$$ getAllAttribute Begin.......");
        TypeInstance typeInstance;
        Map<String, Object> dataMap = new HashMap<String, Object>();
        try {
            LWCNormalizedObject lwcObject = new LWCNormalizedObject(p, null, loc, null);
            TypeInstanceIdentifier typeinstanceidentifier = ClientTypedUtility.getTypeInstanceIdentifier(p);
            typeInstance = TypeInstanceFactory.newTypeInstance(typeinstanceidentifier);
            
            TypeIdentifier typeidentifier = (TypeIdentifier)typeInstance.getIdentifier().getDefinitionIdentifier();
            Set attrs=TypeHelper.getSoftAttributes(typeidentifier);
            Iterator attIt=attrs.iterator();
            String attrFullName="";
            String attrName="";
            int idx=0;
            while(attIt.hasNext()){
                attrFullName=attIt.next().toString();
                idx=attrFullName.lastIndexOf("|");
                attrName=attrFullName.substring(idx+1);
                lwcObject.load(attrName);
                dataMap.put(attrName, lwcObject.get(attrName));
            }
        } catch (IllegalFormatException e) {
            e.printStackTrace();
        } catch (WTException e) {

            e.printStackTrace();
        }
        log.info("$$$$$$$$ getAllAttribute End.......>");
        return dataMap;
    }
    
    /**
     * 
     * @param p
     * @return
     */
    public static Map<String, Object> getAllAttribute(Persistable p)  {
        Locale loc=null;
        try {
            loc = SessionHelper.getLocale();
        } catch (WTException e) {
            e.printStackTrace();
            return null;
            
        }
        return getAllAttribute(p,loc);
    }
    /**
     * 
     * @param p
     * @param key
     * @return
     * @throws WTException
     */
    public static Object getValue(Persistable p, String key) throws WTException {
        Locale loc=null;
        try {
            loc = SessionHelper.getLocale();
        } catch (WTException e) {
            e.printStackTrace();
            return null;
            
        }
        return getValue(p,loc,key);
    }
    
    /**
     * 
     * @param p
     * @param key
     * @return
     * @throws WTException
     */
    public static Object getValue(Persistable p,Locale loc, String key) throws WTException {
        LWCNormalizedObject lwcObject = new LWCNormalizedObject(p, null, loc, null);
        lwcObject.load(key);
        return lwcObject.get(key);

    }
    /***
     * 
     * @param p
     * @param keys
     * @return
     * @throws WTException
     */
    public static Map<String, Object> getMutilValue(Persistable p, String[] keys) throws WTException{
        
        Locale loc=null;
        try {
            loc = SessionHelper.getLocale();
        } catch (WTException e) {
            e.printStackTrace();
            return null;
            
        }
        return getMutilValue(p,loc,keys);
    }
    
    /**
     * 
     * @param p
     * @param keys
     * @return
     * @throws WTException
     */
    public static Map<String, Object> getMutilValue(Persistable p,Locale loc, String[] keys) throws WTException {
        Map<String, Object> dataMap = new HashMap<String, Object>();
        LWCNormalizedObject lwcObject = new LWCNormalizedObject(p, null, loc, null);
        for (int i = 0; i < keys.length; i++) {
            lwcObject.load(keys[i]);
            dataMap.put(keys[i], lwcObject.get(keys[i]));
        }

        return dataMap;

    }

    /**
     * 
     * @param p
     * @param dataMap
     * @return
     * @throws WTException
     */
    public static void setValueBeforeStore(Persistable p,  Map<String, Object> dataMap) throws WTException{
        
        Locale loc=null;
        try {
            loc = SessionHelper.getLocale();
        } catch (WTException e) {
            e.printStackTrace();
            return ;
            
        }
        setValueBeforeStore(p,loc,dataMap);
    }
    
    /**
     * 
     * @param p
     * @param loc
     * @param dataMap
     * @return
     * @throws WTException
     */
    public static void setValueBeforeStore(Persistable p, Locale loc, Map<String, Object> dataMap) throws WTException {
        LWCNormalizedObject lwcObject = new LWCNormalizedObject(p, null, loc, new UpdateOperationIdentifier());
        Iterator<String> keyIt = dataMap.keySet().iterator();
        String key = null;
        lwcObject.load(dataMap.keySet());
        while (keyIt.hasNext()) {
            key = keyIt.next();
            lwcObject.set(key, dataMap.get(key));
        }

        lwcObject.apply();
//        Persistable newP=PersistenceHelper.manager.modify(p);
//        return newP;
    }
    
    /**
     * 
     * @param p
     * @param dataMap
     * @return
     * @throws WTException
     */
    public static void setValue(Persistable p,  Map<String, Object> dataMap) throws WTException{
        
        Locale loc=null;
        try {
            loc = SessionHelper.getLocale();
        } catch (WTException e) {
            e.printStackTrace();
            return ;
            
        }
        setValue(p,loc,dataMap);
    }
    
    /**
     * 
     * @param p
     * @param loc
     * @param dataMap
     * @return
     * @throws WTException
     */
    public static Persistable setValue(Persistable p, Locale loc, Map<String, Object> dataMap) throws WTException {
        LWCNormalizedObject lwcObject = new LWCNormalizedObject(p, null, loc, new UpdateOperationIdentifier());
        Iterator<String> keyIt = dataMap.keySet().iterator();
        String key = null;
        lwcObject.load(dataMap.keySet());
        while (keyIt.hasNext()) {
            key = keyIt.next();
            lwcObject.set(key, dataMap.get(key));
        }

        lwcObject.apply();
        Persistable newP=PersistenceHelper.manager.modify(p);
        return newP;
    }
    /***
     * 
     * @param p
     * @param key
     * @param value
     * @return
     * @throws WTException
     */
    public static Persistable setValue(Persistable p,  String key, Object value) throws WTException {
        Locale loc=null;
        try {
            loc = SessionHelper.getLocale();
        } catch (WTException e) {
            e.printStackTrace();
            return null;
        }
        return setValue(p,loc,key,value);
        
    }
    
    /**
     * 
     * @param p
     * @param loc
     * @param key
     * @param value
     * @return
     * @throws WTException
     */
    public static Persistable setValue(Persistable p, Locale loc, String key, Object value) throws WTException {
        LWCNormalizedObject lwcObject = new LWCNormalizedObject(p, null, loc, new UpdateOperationIdentifier());
        lwcObject.load(key);
        lwcObject.set(key, value);
        lwcObject.apply();
        //PersistenceServerHelper.manager.update(p);
        Persistable newP= PersistenceHelper.manager.modify(p);
        
        return newP;

    }
    
    public static void setValueBeforeStore(Persistable p, String key, Object value) throws WTException {
         setValueBeforeStore(p,SessionHelper.getLocale(),key,value);
   }
    
    
    public static void setValueBeforeStore(Persistable p, Locale loc, String key, Object value) throws WTException {
    	 LWCNormalizedObject lwcObject = new LWCNormalizedObject(p, null, loc, new UpdateOperationIdentifier());
         lwcObject.load(key);
         lwcObject.set(key, value);
         lwcObject.apply();
    }
    
    public static void setStringIBAValue(Persistable persistable,String arrName, String value) throws Exception {
		AttributeDefDefaultView defView = IBADefinitionHelper.service.getAttributeDefDefaultViewByPath(arrName);
		StringDefinition stringDef = null;
		if (defView instanceof StringDefView) {
			stringDef = (StringDefinition) ObjectReference.newObjectReference(((StringDefView) defView).getObjectID()).getObject();
		}
		if (stringDef == null)
			throw new Exception("IBA Def not found error [" + arrName + "]");
		QuerySpec qs = new QuerySpec(StringValue.class);
		qs.appendWhere(new SearchCondition(StringValue.class,"theIBAHolderReference.key", SearchCondition.EQUAL, persistable.getPersistInfo().getObjectIdentifier()),new int[] { 0 });
		qs.appendAnd();
		qs.appendWhere(new SearchCondition(StringValue.class,"definitionReference.key", SearchCondition.EQUAL, stringDef.getPersistInfo().getObjectIdentifier()),new int[] { 0 });
		QueryResult qr = PersistenceHelper.manager.find((StatementSpec) qs);
		if (qr.hasMoreElements()) {
			StringValue strvalue = (StringValue) qr.nextElement();
			strvalue.setValue(value);
			PersistenceHelper.manager.save(strvalue);
		} else {
			StringValue sv = StringValue.newStringValue(stringDef,(IBAHolder) persistable, value);
			PersistenceHelper.manager.save(sv);
		}
	}
    
    /*public static void setStringIBAValue(Persistable persistable, String arrName, String value) throws Exception {
    	AttributeDefDefaultView defView = IBADefinitionHelper.service.getAttributeDefDefaultViewByPath(arrName);
    	StringDefinition stringDef = null;	
    	if (defView instanceof StringDefView) {
			stringDef = (StringDefinition) ObjectReference.newObjectReference(((StringDefView) defView).getObjectID()).getObject();
		}
    	if(stringDef==null)
    		throw new Exception("IBA Def not found error ["+arrName+"]");
    	QuerySpec qs = new QuerySpec(StringValue.class);
		qs.appendWhere(new SearchCondition(StringValue.class,"theIBAHolderReference.key", SearchCondition.EQUAL, persistable.getPersistInfo().getObjectIdentifier()), new int[] { 0 });
		qs.appendAnd();
		qs.appendWhere(new SearchCondition(StringValue.class,"definitionReference.key", SearchCondition.EQUAL, stringDef.getPersistInfo().getObjectIdentifier()), new int[] { 0 });
		QueryResult qr = PersistenceHelper.manager.find((StatementSpec) qs);
		if (qr.hasMoreElements()) {
			StringValue strvalue = (StringValue) qr.nextElement();
			strvalue.setValue(value);
			PersistenceHelper.manager.save(strvalue);
		} else {
			StringValue sv = StringValue.newStringValue(stringDef, (IBAHolder)persistable, value);
			PersistenceHelper.manager.save(sv);
		}
    } */
	
	public static void setIntegerIBAValue(Persistable persistable, String arrName, long value) throws Exception {
    	AttributeDefDefaultView defView = IBADefinitionHelper.service.getAttributeDefDefaultViewByPath(arrName);
    	IntegerDefinition stringDef = null;	
    	if (defView instanceof IntegerDefView) {
			stringDef = (IntegerDefinition) ObjectReference.newObjectReference(((IntegerDefView) defView).getObjectID()).getObject();
		}
    	if(stringDef==null)
    		throw new Exception("IBA Def not found error ["+arrName+"]");
    	QuerySpec qs = new QuerySpec(IntegerValue.class);
		qs.appendWhere(new SearchCondition(IntegerValue.class,"theIBAHolderReference.key", SearchCondition.EQUAL, persistable.getPersistInfo().getObjectIdentifier()), new int[] { 0 });
		qs.appendAnd();
		qs.appendWhere(new SearchCondition(IntegerValue.class,"definitionReference.key", SearchCondition.EQUAL, stringDef.getPersistInfo().getObjectIdentifier()), new int[] { 0 });
		QueryResult qr = PersistenceHelper.manager.find((StatementSpec) qs);
		if (qr.hasMoreElements()) {
			IntegerValue strvalue = (IntegerValue) qr.nextElement();
			strvalue.setValue(value);
			PersistenceHelper.manager.save(strvalue);
		} else {
			IntegerValue sv = IntegerValue.newIntegerValue(stringDef, (IBAHolder)persistable, value);
			PersistenceHelper.manager.save(sv);
		}
    } 
	
	public static void setTimestampIBAValue(Persistable persistable, String arrName, Timestamp value) throws Exception {
    	AttributeDefDefaultView defView = IBADefinitionHelper.service.getAttributeDefDefaultViewByPath(arrName);
    	TimestampDefinition stringDef = null;	
    	if (defView instanceof TimestampDefView) {
			stringDef = (TimestampDefinition) ObjectReference.newObjectReference(((TimestampDefView) defView).getObjectID()).getObject();
		}
    	if(stringDef==null)
    		throw new Exception("IBA Def not found error ["+arrName+"]");
    	QuerySpec qs = new QuerySpec(TimestampValue.class);
		qs.appendWhere(new SearchCondition(TimestampValue.class,"theIBAHolderReference.key", SearchCondition.EQUAL, persistable.getPersistInfo().getObjectIdentifier()), new int[] { 0 });
		qs.appendAnd();
		qs.appendWhere(new SearchCondition(TimestampValue.class,"definitionReference.key", SearchCondition.EQUAL, stringDef.getPersistInfo().getObjectIdentifier()), new int[] { 0 });
		QueryResult qr = PersistenceHelper.manager.find((StatementSpec) qs);
		if (qr.hasMoreElements()) {
			TimestampValue strvalue = (TimestampValue) qr.nextElement();
			strvalue.setValue(value);
			PersistenceHelper.manager.save(strvalue);
		} else {
			TimestampValue sv = TimestampValue.newTimestampValue(stringDef, (IBAHolder)persistable, value);
			PersistenceHelper.manager.save(sv);
		}
    } 
	
	
	public static void setFloatIBAValue(Persistable persistable, String arrName, float value) throws Exception {
    	AttributeDefDefaultView defView = IBADefinitionHelper.service.getAttributeDefDefaultViewByPath(arrName);
    	FloatDefinition stringDef = null;	
    	if (defView instanceof FloatDefView) {
			stringDef = (FloatDefinition) ObjectReference.newObjectReference(((FloatDefView) defView).getObjectID()).getObject();
		}
    	if(stringDef==null)
    		throw new Exception("IBA Def not found error ["+arrName+"]");
    	QuerySpec qs = new QuerySpec(FloatValue.class);
		qs.appendWhere(new SearchCondition(FloatValue.class,"theIBAHolderReference.key", SearchCondition.EQUAL, persistable.getPersistInfo().getObjectIdentifier()), new int[] { 0 });
		qs.appendAnd();
		qs.appendWhere(new SearchCondition(FloatValue.class,"definitionReference.key", SearchCondition.EQUAL, stringDef.getPersistInfo().getObjectIdentifier()), new int[] { 0 });
		QueryResult qr = PersistenceHelper.manager.find((StatementSpec) qs);
		if (qr.hasMoreElements()) {
			FloatValue strvalue = (FloatValue) qr.nextElement();
			strvalue.setValue(value);
			PersistenceHelper.manager.save(strvalue);
		} else {
			FloatValue sv = FloatValue.newFloatValue(stringDef, (IBAHolder)persistable, value, 0);
			PersistenceHelper.manager.save(sv);
		}
    } 
	
	public static void setBooleanIBAValue(Persistable persistable, String arrName, boolean value) throws Exception {
    	AttributeDefDefaultView defView = IBADefinitionHelper.service.getAttributeDefDefaultViewByPath(arrName);
    	BooleanDefinition stringDef = null;	
    	if (defView instanceof BooleanDefView) {
			stringDef = (BooleanDefinition) ObjectReference.newObjectReference(((BooleanDefView) defView).getObjectID()).getObject();
		}
    	if(stringDef==null)
    		throw new Exception("IBA Def not found error ["+arrName+"]");
    	QuerySpec qs = new QuerySpec(BooleanValue.class);
		qs.appendWhere(new SearchCondition(BooleanValue.class,"theIBAHolderReference.key", SearchCondition.EQUAL, persistable.getPersistInfo().getObjectIdentifier()), new int[] { 0 });
		qs.appendAnd();
		qs.appendWhere(new SearchCondition(BooleanValue.class,"definitionReference.key", SearchCondition.EQUAL, stringDef.getPersistInfo().getObjectIdentifier()), new int[] { 0 });
		QueryResult qr = PersistenceHelper.manager.find((StatementSpec) qs);
		if (qr.hasMoreElements()) {
			BooleanValue strvalue = (BooleanValue) qr.nextElement();
			strvalue.setValue(value);
			PersistenceHelper.manager.save(strvalue);
		} else {
			BooleanValue sv = BooleanValue.newBooleanValue(stringDef, (IBAHolder)persistable, value);
			PersistenceHelper.manager.save(sv);
		}
    }
	
    /**
     * 
     * @param p
     * @param key
     * @return
     * @throws WTException
     */
    public static LWCNormalizedObject getValues(Persistable p,List<String> keys) throws WTException {
    	Locale loc = SessionHelper.getLocale();
        LWCNormalizedObject lwcObject = new LWCNormalizedObject(p, null, loc, null);
        lwcObject.load(keys);
        return lwcObject;
    }
    
    
    /**
     * 报表专用接口
     * @param p
     * @param key
     * @return
     * @throws WTException
     */
    public static  Map<String, String>  getIBAValues(Persistable p,List<String> keys) throws WTException {
    	Map <String, String> dataMap = new HashMap();
    	String returnStr = "";
    	Locale loc = SessionHelper.getLocale();
        LWCNormalizedObject lwcObject = new LWCNormalizedObject(p, null, loc, null);
        lwcObject.load(keys);
        for(String key : keys)
        {
        	Object obj = lwcObject.get(key);
        	if(obj == null){
        	    dataMap.put(key, "");
        	    continue;
        	}else{
                if(obj instanceof String)
                {
                    returnStr = (obj == null) ? "" : (String) obj;
                    dataMap.put(key, returnStr);
                }else if(obj instanceof Timestamp)
                {
                    returnStr = (obj == null) ? "" : ((Timestamp)obj).toGMTString();
                    dataMap.put(key, returnStr);
                }else
                {
                    if(obj != null)
                    {
                        dataMap.put(key, obj.toString());
                    }else
                    {
                        dataMap.put(key, "");
                    }
                } 
        	}
        }
        return dataMap;
    }
    
}

